﻿#include "EngineDefaultPackage.h"

#include "Object/NewObject.h"
#include "Containers/Vector.h"
#include "Texture/Texture2D.h"
#include "Texture/TextureCube.h"
#include "Texture/PNGReadWrite.h"
#include "Material/Shader.h"
#include "Mesh/StaticMesh.h"
#include "Material/Material.h"

#include "Asset/AssetObject.h"
#include "Asset/AssetPath.h"

#include "Render/RenderContext.h"
#include "Framework/Application.h"

#include <math.h>

static REngineDefaultPackage* Instance=nullptr;

static TSharedObjectPtr<RTexture2D> CreateEngineIcon()
{
    TVector< uint8_t> IconFileData=
    {
        #include "Icons/EngineIcon.png.h"
    };

    return RTexture2D::CreateFromPNGFileData(std::move(IconFileData));
}


static TSharedObjectPtr<RTexture2D> CreateMinimizeIcon()
{
    TVector< uint8_t> IconFileData=
    {
        #include "Icons/minimize.png.h"
    };

    return RTexture2D::CreateFromPNGFileData(std::move(IconFileData));
}

static TSharedObjectPtr<RTexture2D> CreateMaximizeIcon()
{
    TVector< uint8_t> IconFileData=
    {
        #include "Icons/maximize.png.h"
    };

    return RTexture2D::CreateFromPNGFileData(std::move(IconFileData));
}



static TSharedObjectPtr<RTexture2D> CreateRestoreIcon()
{
    TVector< uint8_t> IconFileData=
    {
        #include "Icons/restore.png.h"
    };

    return RTexture2D::CreateFromPNGFileData(std::move(IconFileData));
}

static TSharedObjectPtr<RTexture2D> CreateCloseIcon()
{
    TVector< uint8_t> IconFileData=
    {
        #include "Icons/close.png.h"
    };

    return RTexture2D::CreateFromPNGFileData(std::move(IconFileData));
}


static TSharedObjectPtr<RTexture2D> CreateFolderIcon()
{
    TVector< uint8_t> IconFileData=
    {
        #include "Icons/Folder.png.h"
    };

    return RTexture2D::CreateFromPNGFileData(std::move(IconFileData));
}

static TSharedObjectPtr<RTexture2D> CreateAddFolderIcon()
{
    TVector< uint8_t> IconFileData=
    {
        #include "Icons/AddFolder.png.h"
    };

    return RTexture2D::CreateFromPNGFileData(std::move(IconFileData));
}

static TSharedObjectPtr<RTexture2D> CreateAddFileIcon()
{
    TVector< uint8_t> IconFileData=
    {
        #include "Icons/AddFile.png.h"
    };

    return RTexture2D::CreateFromPNGFileData(std::move(IconFileData));
}

static TSharedObjectPtr<RTexture2D> CreateRefreshIcon()
{
    TVector< uint8_t> IconFileData=
    {
        #include "Icons/Refresh.png.h"
    };

    return RTexture2D::CreateFromPNGFileData(std::move(IconFileData));
}

static TSharedObjectPtr<RTexture2D> CreateCheckBoxCheckedIcon()
{
    TVector< uint8_t> IconFileData=
    {
        #include "Icons/CheckBox_Checked.png.h"
    };

    return RTexture2D::CreateFromPNGFileData(std::move(IconFileData));
}

static TSharedObjectPtr<RTexture2D> CreateCheckBoxUnCheckedIcon()
{
    TVector< uint8_t> IconFileData=
    {
        #include "Icons/CheckBox_Unchecked.png.h"
    };

    return RTexture2D::CreateFromPNGFileData(std::move(IconFileData));
}

static TSharedObjectPtr<RTexture2D> CreateCheckBoxNotAllCheckedIcon()
{
    TVector< uint8_t> IconFileData=
    {
        #include "Icons/CheckBox_NotAllChecked.png.h"
    };

    return RTexture2D::CreateFromPNGFileData(std::move(IconFileData));
}

static TSharedObjectPtr<RTextureCube> CreateDefaultSkyBoxTexture()
{
    TVector<uint8_t> FrontFaceData={
        #include "Icons/Skybox/Front.png.h"
    };
    TVector<uint8_t> BackFaceData={
        #include "Icons/Skybox/Back.png.h"
    };
    TVector<uint8_t> LeftFaceData={
        #include "Icons/Skybox/Left.png.h"
    };
    TVector<uint8_t> RightFaceData={
        #include "Icons/Skybox/Right.png.h"
    };
    TVector<uint8_t> TopFaceData={
        #include "Icons/Skybox/Top.png.h"
    };
    TVector<uint8_t> BottomFaceData={
        #include "Icons/Skybox/Bottom.png.h"
    };

    RTextureCube::STextureCubeCreateInfo CreateInfo;
    WH::ReadPNGFromFileData(FrontFaceData,CreateInfo.Front,CreateInfo.Format,CreateInfo.Width,CreateInfo.Height,CreateInfo.Pitch);
    WH::ReadPNGFromFileData(BackFaceData,CreateInfo.Back,CreateInfo.Format,CreateInfo.Width,CreateInfo.Height,CreateInfo.Pitch);
    WH::ReadPNGFromFileData(LeftFaceData,CreateInfo.Left,CreateInfo.Format,CreateInfo.Width,CreateInfo.Height,CreateInfo.Pitch);
    WH::ReadPNGFromFileData(RightFaceData,CreateInfo.Right,CreateInfo.Format,CreateInfo.Width,CreateInfo.Height,CreateInfo.Pitch);
    WH::ReadPNGFromFileData(TopFaceData,CreateInfo.Top,CreateInfo.Format,CreateInfo.Width,CreateInfo.Height,CreateInfo.Pitch);
    WH::ReadPNGFromFileData(BottomFaceData,CreateInfo.Bottom,CreateInfo.Format,CreateInfo.Width,CreateInfo.Height,CreateInfo.Pitch);

    return RTextureCube::CreateFromCreateInfo(std::move(CreateInfo));
}

static TSharedObjectPtr<RShader> CreateDefaultMeshVertexShader()
{
    TVector<uint8_t> ShaderData={
        #include "Shaders/DefaultMesh.vert.spv.h"
    };
    return RShader::CreateShader(ShaderData,EShaderStage::Vertex);
}

static TSharedObjectPtr<RShader> CreateDefaultMeshFragmentShader()
{
    TVector<uint8_t> ShaderData={
        #include "Shaders/DefaultMesh.frag.spv.h"
    };
    return RShader::CreateShader(ShaderData,EShaderStage::Fragment);
}

static TSharedObjectPtr<RShader> CreateDefaultSelfLightingFragmentShader()
{
    TVector<uint8_t> ShaderData={
        #include "Shaders/DefaultSelfLightMesh.frag.spv.h"
    };
    return RShader::CreateShader(ShaderData,EShaderStage::Fragment);

}

static TSharedObjectPtr<RShader> CreateDefaultSkyBoxFragmentShader()
{
    TVector<uint8_t> ShaderData={
        #include "Shaders/SkyBox/SkyBox.frag.spv.h"
    };
    return RShader::CreateShader(ShaderData,EShaderStage::Fragment);
}

static TSharedObjectPtr<RStaticMesh> CreateCubeMesh()
{

    TSharedObjectPtr<RStaticMesh>  Cube=
        RStaticMesh::CreateMesh(TVector<SVertex>({
            // left face
            SVertex(-0.5f, -0.5f, -0.5f, 0.5f, 0.f,  -0.5f,0,0),  // lft-top-front
            SVertex(-0.5f, -0.5f, 0.5f ,  0.f, 0.f,  -0.5f,0,0),   // lft-top-back
            SVertex(-0.5f, 0.5f, 0.5f ,0.f, 0.5f,    -0.5f,0,0),    // lft-btm-back
            SVertex(-0.5f, -0.5f, -0.5f ,  0.5f, 0.f,-0.5f,0,0) ,  // lft-top-front
            SVertex(-0.5f, 0.5f, 0.5f , 0.f, 0.5f,    -0.5f,0,0) ,    // lft-btm-back
            SVertex(-0.5f, 0.5f, -0.5f,0.5f, 0.5f,    -0.5f,0,0),   // lft-btm-front
            // front face
            SVertex(-0.5f, -0.5f, -0.5f,0.f, 0.f,   0,0,-0.5f),  // lft-top-front
            SVertex(0.5f, 0.5f, -0.5f,0.5f, 0.5f,     0,0,-0.5f),    // rgt-btm-front
            SVertex(0.5f, -0.5f, -0.5f,0.5f, 0.f,     0,0,-0.5f),   // rgt-top-front
            SVertex(0.5f, 0.5f, -0.5f,0.5f, 0.5f,       0,0,-0.5f),    // rgt-btm-front
            SVertex(-0.5f, -0.5f, -0.5f,0.f, 0.f,    0,0,-0.5f),  // lft-top-front
            SVertex(-0.5f, 0.5f, -0.5f,0.f, 0.5f,      0,0,-0.5f),   // lft-btm-front
            // top face
            SVertex(-0.5f, -0.5f, -0.5f,0.f, 0.5f,  0,-0.5f,0),  // lft-top-front
            SVertex(0.5f, -0.5f, -0.5f,0.5f, 0.5f,   0,-0.5f,0),   // rgt-top-front
            SVertex(0.5f, -0.5f, 0.5f,0.5f, 0.f ,   0,-0.5f,0),    // rgt-top-back
            SVertex(-0.5f, -0.5f, 0.5f,0.f, 0.f,    0,-0.5f,0),   // lft-top-back
            SVertex(-0.5f, -0.5f, -0.5f,0.f, 0.5f,   0,-0.5f,0),  // lft-top-front
            SVertex(0.5f, -0.5f, 0.5f,0.5f, 0.f,     0,-0.5f,0),    // rgt-top-back
            // bottom face
            SVertex(-0.5f, 0.5f, -0.5f,0.f, 0.f,  0,0.5f,0),  // lft-btm-front
            SVertex(-0.5f, 0.5f, 0.5f,0.f, 0.5f,  0,0.5f,0),   // lft-btm-back
            SVertex(0.5f, 0.5f, 0.5f,0.5f, 0.5f ,  0,0.5f,0),    // rgt-btm-back
            SVertex(0.5f, 0.5f, -0.5f,0.5f, 0.f,  0,0.5f,0),   // rgt-btm-front
            SVertex(-0.5f, 0.5f, -0.5f,0.f, 0.f,  0,0.5f,0),  // lft-btm-front
            SVertex(0.5f, 0.5f, 0.5f,0.5f, 0.5f,   0,0.5f,0),    // rgt-btm-back
            // right face
            SVertex(0.5f, 0.5f, -0.5f,0.f, 0.5f , 0.5f,0,0),   // rgt-btm-front
            SVertex(0.5f, 0.5f, 0.5f,0.5f, 0.5f  , 0.5f,0,0),    // rgt-btm-back
            SVertex(0.5f, -0.5f, 0.5f,0.5f, 0.f , 0.5f,0,0),   // rgt-top-back
            SVertex(0.5f, 0.5f, -0.5f,0.f, 0.5f,  0.5f,0,0),   // rgt-btm-front
            SVertex(0.5f, -0.5f, 0.5f,0.5f, 0.f , 0.5f,0,0),   // rgt-top-back
            SVertex(0.5f, -0.5f, -0.5f,0.f, 0.f, 0.5f,0,0),  // rgt-top-front
            // back face
            SVertex(-0.5f, 0.5f, 0.5f,0.5f, 0.5f,  0,0,0.5f),   // lft-btm-back
            SVertex(-0.5f, -0.5f, 0.5f,0.5f, 0.f,  0,0,0.5f),  // lft-top-back
            SVertex(0.5f, 0.5f, 0.5f,0.f, 0.5f,    0,0,0.5f),    // rgt-btm-back
            SVertex(0.5f, 0.5f, 0.5f,0.f, 0.5f,    0,0,0.5f),    // rgt-btm-back
            SVertex(-0.5f, -0.5f, 0.5f,0.5f, 0.f,  0,0,0.5f),  // lft-top-back
            SVertex(0.5f, -0.5f, 0.5f,0.f, 0.f,   0,0,0.5f)   // rgt-top-back
        })
        ,TVector<uint32_t>()
        );

    return Cube;
}

static TSharedObjectPtr<RStaticMesh> CreateSphereMesh()
{
    TVector<SVertex> Vertices;
    
    const int32_t NumSegments = 32;
    const int32_t NumRings = 16;
    const float Radius = 0.5f;

    for (int32_t RingIndex=0; RingIndex<NumRings; RingIndex++)
    {
        float Phi = (float)RingIndex / (float)(NumRings - 1);
        float Y = cos(Phi * CMath::Pi);
        float R = sin(Phi *  CMath::Pi);

        for (int32_t SegmentIndex=0; SegmentIndex<NumSegments; SegmentIndex++)
        {
            float Theta = (float)SegmentIndex / (float)(NumSegments - 1);
            float X = cos(Theta * 2 * CMath::Pi) * R;
            float Z = sin(Theta * 2 * CMath::Pi) * R;

            Vertices.Add(SVertex(X * Radius, Y * Radius, Z * Radius
                , Theta, Phi
                , X, Y, Z));
        }
    }

    TVector<uint32_t> Indices;
    for (int32_t RingIndex=0; RingIndex<NumRings-1; RingIndex++)
    {
        for (int32_t SegmentIndex=0; SegmentIndex<NumSegments-1; SegmentIndex++)
        {
            int32_t Index0 = RingIndex * NumSegments + SegmentIndex;
            int32_t Index1 = Index0 + 1;
            int32_t Index2 = (RingIndex + 1) * NumSegments + SegmentIndex;
            int32_t Index3 = Index2 + 1;

            Indices.Add(Index0);
            Indices.Add(Index1);
            Indices.Add(Index2);

            Indices.Add(Index1);
            Indices.Add(Index3);
            Indices.Add(Index2);
        }
    }


    TSharedObjectPtr<RStaticMesh> Sphere=
        RStaticMesh::CreateMesh(Vertices,Indices);
    return Sphere;

}

static TSharedObjectPtr<RStaticMesh> CreateAxisMesh()
{
    //axis mesh have a sylinder and a cone
    //the axis toward +X;
    //do not have UV, do not use texture

    TVector<SVertex> Vertices;
    TVector<uint32_t> Indices;

    //sylinder
    const int32_t NumSegments = 16;
    const float Radius = 0.05f; //radius of circle of sylinder
    const float Height = 1.0f; //height of sylinder

    //side face of sylinder
    //only have two ring
    for (int32_t RingIndex=0; RingIndex<2; RingIndex++)
    {
        float X=RingIndex* Height;
        for (int32_t SegmentIndex=0; SegmentIndex<NumSegments; SegmentIndex++)
        {
            float Theta = (float)SegmentIndex / (float)(NumSegments - 1);
            float Z = cos(Theta * 2 * CMath::Pi) * Radius;
            float Y = sin(Theta * 2 * CMath::Pi) * Radius;

            Vertices.Add(SVertex(X, Y, Z
                , 0, 0 //UV ,any uv is ok, do not use texture
                , 0, Y, Z));
        }
    }

    //add side face indices
    for (int32_t SegmentIndex=0; SegmentIndex<NumSegments-1; SegmentIndex++)
    {
        int32_t Index0 = SegmentIndex;
        int32_t Index1 = Index0 + 1;
        int32_t Index2 = NumSegments + SegmentIndex;
        int32_t Index3 = Index2 + 1;

        Indices.Add(Index0);
        Indices.Add(Index2);
        Indices.Add(Index1);

        Indices.Add(Index1);
        Indices.Add(Index2);
        Indices.Add(Index3);
    }

    //add bottom face of sylinder
    int64_t BottomFaceStartIndex=Vertices.Num();
    for (int32_t SegmentIndex=0; SegmentIndex<NumSegments; SegmentIndex++)
    {
        float Theta = (float)SegmentIndex / (float)(NumSegments - 1);
        float Z = cos(Theta * 2 * CMath::Pi) * Radius;
        float Y = sin(Theta * 2 * CMath::Pi) * Radius;

        Vertices.Add(SVertex(0, Y, Z
            , 0, 0 //UV ,any uv is ok, do not use texture
            , -1, 0, 0));
    }

    //add bottom face center vertex
    int64_t BottomFaceCenterIndex=Vertices.Num();
    Vertices.Add(SVertex(0, 0, 0
        , 0, 0 //UV ,any uv is ok, do not use texture
        , -1, 0, 0));

    //add bottom face indices
    for (int32_t SegmentIndex=0; SegmentIndex<NumSegments-1; SegmentIndex++)
    {
        int32_t Index0 = BottomFaceStartIndex + SegmentIndex;
        int32_t Index1 = Index0 + 1;
        int32_t Index2 = BottomFaceCenterIndex;

        Indices.Add(Index0);
        Indices.Add(Index1);
        Indices.Add(Index2);
    }


    //cone
    //cone have a circle bottom face and a side face
    const float ConeRadius = 0.1f; //radius of circle of cone
    const float ConeHeight = 0.2f; //height of cone

    //side face of cone
    //only have one ring

    //add side face vertext and indices at the same time
    int64_t ConeSideFaceStartIndex=Vertices.Num();
    for (int32_t SegmentIndex=0; SegmentIndex<NumSegments-1; SegmentIndex++)
    {
        float LeftTheta = (float)SegmentIndex / (float)(NumSegments - 1);

        int64_t RightSegmentIndex=SegmentIndex+1;
        if(RightSegmentIndex==NumSegments)
        {
            RightSegmentIndex=0;
        }
        float RightTheta = (float)(RightSegmentIndex) / (float)(NumSegments - 1);

        float LeftZ = cos(LeftTheta * 2 * CMath::Pi) * ConeRadius;
        float LeftY = sin(LeftTheta * 2 * CMath::Pi) * ConeRadius;

        float RightZ = cos(RightTheta * 2 * CMath::Pi) * ConeRadius;
        float RightY = sin(RightTheta * 2 * CMath::Pi) * ConeRadius;

        int64_t Index0=Vertices.Num();
        Vertices.Add(SVertex(Height, LeftY, LeftZ
            , 0, 0 //UV ,any uv is ok, do not use texture
            , ConeRadius
            , sin(LeftTheta * 2 * CMath::Pi) *ConeHeight 
            , cos(LeftTheta * 2 * CMath::Pi) *ConeHeight ));

        int64_t Index1=Vertices.Num();
        Vertices.Add(SVertex(Height, RightY, RightZ
            , 0, 0 //UV ,any uv is ok, do not use texture
            , ConeRadius
            , sin(RightTheta * 2 * CMath::Pi) *ConeHeight 
            , cos(RightTheta * 2 * CMath::Pi) *ConeHeight ));

        int64_t Index2=Vertices.Num();
        Vertices.Add(SVertex(Height+ConeHeight, 0, 0
            , 0, 0 //UV ,any uv is ok, do not use texture
            , ConeRadius
            , sin((LeftTheta+RightTheta) *0.5 * 2 * CMath::Pi) *ConeHeight
            , cos((LeftTheta+RightTheta) *0.5 * 2 * CMath::Pi) *ConeHeight ));

        Indices.Add(Index0);
        Indices.Add(Index2);
        Indices.Add(Index1);
    }

    //bottom face of cone
    int64_t ConeBottomFaceStartIndex=Vertices.Num();
    for(int32_t SegmentIndex=0;SegmentIndex<NumSegments;SegmentIndex++)
    {
        float Theta = (float)SegmentIndex / (float)(NumSegments - 1);
        float Z = cos(Theta * 2 * CMath::Pi) * ConeRadius;
        float Y = sin(Theta * 2 * CMath::Pi) * ConeRadius;

        Vertices.Add(SVertex(Height, Y, Z
            , 0, 0 //UV ,any uv is ok, do not use texture
            , -1, 0, 0));
    }

    //add bottom face center vertex
    int64_t ConeBottomFaceCenterIndex=Vertices.Num();
    Vertices.Add(SVertex(Height, 0, 0
        , 0, 0 //UV ,any uv is ok, do not use texture
        , -1, 0, 0));

    //add bottom face indices
    for (int32_t SegmentIndex=0; SegmentIndex<NumSegments-1; SegmentIndex++)
    {
        int32_t Index0 = ConeBottomFaceStartIndex + SegmentIndex;
        int32_t Index1 = Index0 + 1;
        int32_t Index2 = ConeBottomFaceCenterIndex;

        Indices.Add(Index0);
        Indices.Add(Index1);
        Indices.Add(Index2);
    }

    TSharedObjectPtr<RStaticMesh> Axis=
        RStaticMesh::CreateMesh(Vertices,Indices);

    return Axis;
}

            


void REngineDefaultPackage::Initialize()
{
    // create render object require render context to be initialized
    GetApplication()->MakeSureInitialized<RRenderContext>();

    Instance=this;
    
    TSharedObjectPtr<RAssetObject> DefaultAssetObject=WH::GetDefaultAssetObject();

    EngineIcon=CreateEngineIcon();
    MinimizeIcon=CreateMinimizeIcon();
    MaximizeIcon=CreateMaximizeIcon();
    RestoreIcon=CreateRestoreIcon();
    CloseIcon=CreateCloseIcon();
    FolderIcon=CreateFolderIcon();
    AddFolderIcon=CreateAddFolderIcon();
    AddFileIcon=CreateAddFileIcon();
    RefreshIcon=CreateRefreshIcon();
    CheckBoxCheckedIcon=CreateCheckBoxCheckedIcon();
    CheckBoxUnCheckedIcon=CreateCheckBoxUnCheckedIcon();
    CheckBoxNotAllCheckedIcon=CreateCheckBoxNotAllCheckedIcon();
    DefaultSkyBoxTexture =CreateDefaultSkyBoxTexture();

    DefaultMeshVertexShader = CreateDefaultMeshVertexShader();
    DefaultMeshFragmentShader = CreateDefaultMeshFragmentShader();
    DefaultSelfLightingFragmentShader = CreateDefaultSelfLightingFragmentShader();
    DefaultSkyBoxFragmentShader = CreateDefaultSkyBoxFragmentShader();

    {
        TVector<uint8_t> ShaderData={
            #include "Shaders/SingleColorMaterial.frag.spv.h"
        };
        SingleColorFragmentShader= RShader::CreateShader(ShaderData,EShaderStage::Fragment);
        SingleColorFragmentShader->SetNodeName(U"SingleColorFragmentShader");
        SingleColorFragmentShader->SetOwner(WH::GetDefaultAssetObject().Get());
    }

    RMaterial::SMaterialCreateInfo DefaultMaterialCreateInfo;
    DefaultMaterialCreateInfo.VertexShader=DefaultMeshVertexShader;
    DefaultMaterialCreateInfo.FragmentShader=DefaultMeshFragmentShader;
    DefaultMaterialCreateInfo.PipelineType=ERenderMaterialType::Opaque;

    DefaultMaterial=RMaterial::Create(DefaultMaterialCreateInfo);


    RMaterial::SMaterialCreateInfo DefaultSkyBoxMaterialCreateInfo;
    DefaultSkyBoxMaterialCreateInfo.VertexShader=DefaultMeshVertexShader;
    DefaultSkyBoxMaterialCreateInfo.FragmentShader=DefaultSkyBoxFragmentShader;
    DefaultSkyBoxMaterialCreateInfo.PipelineType=ERenderMaterialType::Unlit;
    DefaultSkyBoxMaterialCreateInfo.bDoubleSide=true;
    DefaultSkyBoxMaterialCreateInfo.TextureCubes.Add(DefaultSkyBoxTexture);

    DefaultSkyBoxMaterial=RMaterial::Create(DefaultSkyBoxMaterialCreateInfo);

    CubeMesh=CreateCubeMesh();
    SphereMesh=CreateSphereMesh();
    AxisMesh=CreateAxisMesh();

    //set owner for all object
    EngineIcon->SetNodeName(U"EngineIcon");
    EngineIcon->SetOwner(DefaultAssetObject.Get());
    MinimizeIcon->SetNodeName(U"MinimizeIcon");
    MinimizeIcon->SetOwner(DefaultAssetObject.Get());
    MaximizeIcon->SetNodeName(U"MaximizeIcon");
    MaximizeIcon->SetOwner(DefaultAssetObject.Get());
    RestoreIcon->SetNodeName(U"RestoreIcon");
    RestoreIcon->SetOwner(DefaultAssetObject.Get());
    CloseIcon->SetNodeName(U"CloseIcon");
    CloseIcon->SetOwner(DefaultAssetObject.Get());
    FolderIcon->SetNodeName(U"FolderIcon");
    FolderIcon->SetOwner(DefaultAssetObject.Get());
    AddFolderIcon->SetNodeName(U"AddFolderIcon");
    AddFolderIcon->SetOwner(DefaultAssetObject.Get());
    AddFileIcon->SetNodeName(U"AddFileIcon");
    AddFileIcon->SetOwner(DefaultAssetObject.Get());
    RefreshIcon->SetNodeName(U"RefreshIcon");
    RefreshIcon->SetOwner(DefaultAssetObject.Get());
    CheckBoxCheckedIcon->SetNodeName(U"CheckBoxCheckedIcon");
    CheckBoxCheckedIcon->SetOwner(DefaultAssetObject.Get());
    CheckBoxUnCheckedIcon->SetNodeName(U"CheckBoxUnCheckedIcon");
    CheckBoxUnCheckedIcon->SetOwner(DefaultAssetObject.Get());
    CheckBoxNotAllCheckedIcon->SetNodeName(U"CheckBoxNotAllCheckedIcon");
    CheckBoxNotAllCheckedIcon->SetOwner(DefaultAssetObject.Get());
    DefaultSkyBoxTexture ->SetNodeName(U"DefaultSkyBoxTexture");
    DefaultSkyBoxTexture ->SetOwner(DefaultAssetObject.Get());

    DefaultMeshVertexShader->SetNodeName(U"DefaultMeshVertexShader");
    DefaultMeshVertexShader->SetOwner(DefaultAssetObject.Get());
    DefaultMeshFragmentShader->SetNodeName(U"DefaultMeshFragmentShader");
    DefaultMeshFragmentShader->SetOwner(DefaultAssetObject.Get());
    DefaultSelfLightingFragmentShader->SetNodeName(U"DefaultSelfLightingFragmentShader");
    DefaultSelfLightingFragmentShader->SetOwner(DefaultAssetObject.Get());
    DefaultSkyBoxFragmentShader->SetNodeName(U"DefaultSkyBoxFragmentShader");
    DefaultSkyBoxFragmentShader->SetOwner(DefaultAssetObject.Get());

    DefaultMaterial->SetNodeName(U"棋盘格材质");
    DefaultMaterial->SetOwner(DefaultAssetObject.Get());

    DefaultSkyBoxMaterial->SetNodeName(U"天空盒材质");
    DefaultSkyBoxMaterial->SetOwner(DefaultAssetObject.Get());

    CubeMesh->SetNodeName(U"立方体网格");
    CubeMesh->SetOwner(DefaultAssetObject.Get());

    SphereMesh->SetNodeName(U"球形网格");
    SphereMesh->SetOwner(DefaultAssetObject.Get());

    AxisMesh->SetNodeName(U"坐标轴网格");
    AxisMesh->SetOwner(DefaultAssetObject.Get());

}

void REngineDefaultPackage::Deinitialize()
{
    Instance=nullptr;
}

REngineDefaultPackage *REngineDefaultPackage::Get()
{
    assert(Instance!=nullptr);
    return Instance;
}

TSharedObjectPtr<RTexture2D> REngineDefaultPackage::GetEngineIcon()
{
    return EngineIcon;
}

TSharedObjectPtr<RTexture2D> REngineDefaultPackage::GetMinimizeIcon()
{
    return MinimizeIcon;
}

TSharedObjectPtr<RTexture2D> REngineDefaultPackage::GetMaximizeIcon()
{
    return MaximizeIcon;
}

TSharedObjectPtr<RTexture2D> REngineDefaultPackage::GetRestoreIcon()
{
    return RestoreIcon;
}

TSharedObjectPtr<RTexture2D> REngineDefaultPackage::GetCloseIcon()
{
    return CloseIcon;
}

TSharedObjectPtr<RTexture2D> REngineDefaultPackage::GetFolderIcon()
{
    return FolderIcon;
}

TSharedObjectPtr<RTexture2D> REngineDefaultPackage::GetAddFolderIcon()
{
    return AddFolderIcon;
}

TSharedObjectPtr<RTexture2D> REngineDefaultPackage::GetAddFileIcon()
{
    return AddFileIcon;
}

TSharedObjectPtr<RTexture2D> REngineDefaultPackage::GetRefreshIcon()
{
    return RefreshIcon;
}

TSharedObjectPtr<RTexture2D> REngineDefaultPackage::GetCheckBoxCheckedIcon()
{
    return CheckBoxCheckedIcon;
}

TSharedObjectPtr<RTexture2D> REngineDefaultPackage::GetCheckBoxUnCheckedIcon()
{
    return CheckBoxUnCheckedIcon;
}

TSharedObjectPtr<RTexture2D> REngineDefaultPackage::GetCheckBoxNotAllCheckedIcon()
{
    return CheckBoxNotAllCheckedIcon;
}

TSharedObjectPtr<RShader> REngineDefaultPackage::GetDefaultMeshVertexShader()
{
    return DefaultMeshVertexShader;
}


TSharedObjectPtr<RShader> REngineDefaultPackage::GetDefaultMeshFragmentShader()
{
    return DefaultMeshFragmentShader;
}

TSharedObjectPtr<RShader> REngineDefaultPackage::GetDefaultSelfLightingFragmentShader()
{
    return DefaultSelfLightingFragmentShader;
}

TSharedObjectPtr<RShader> REngineDefaultPackage::GetDefaultSkyBoxFragmentShader()
{
    return DefaultSkyBoxFragmentShader;
}

TSharedObjectPtr<RShader> REngineDefaultPackage::GetSingleColorFragmentShader()
{
    return SingleColorFragmentShader;
}

TSharedObjectPtr<RMaterial> REngineDefaultPackage::GetDefaultMaterial()
{
    return DefaultMaterial;
}

TSharedObjectPtr<RMaterial> REngineDefaultPackage::GetDefaultSkyBoxMaterial()
{
    return DefaultSkyBoxMaterial;
}

TSharedObjectPtr<RStaticMesh> REngineDefaultPackage::GetCubeMesh()
{
    return CubeMesh;
}

TSharedObjectPtr<RStaticMesh> REngineDefaultPackage::GetSphereMesh()
{
    return SphereMesh;
}

TSharedObjectPtr<RStaticMesh> REngineDefaultPackage::GetAxisMesh()
{
    return AxisMesh;
}

static TWeakObjectPtr<RAssetObject> WeakDefaultAssetObject;

TSharedObjectPtr<RAssetObject> WH::GetDefaultAssetObject()
{
    if(!WeakDefaultAssetObject)
    {
        //create default asset object
        TSharedObjectPtr<RAssetObject> DefaultAssetObject=NewObject<RAssetObject>((RObject*)WH::GetRootObject());
        DefaultAssetObject->SetNodeName(U"DefaultAssetObject");
        DefaultAssetObject->SetAssetPath(
            SAssetPath(
                RObject::StaticClass()
                ,CString(U"Engine")
                ,CString(U"./")
                ,CString(U"DefaultAsset")
                )
        );
        DefaultAssetObject->bAlwaysInMemory=true;
        
        WeakDefaultAssetObject=DefaultAssetObject;

        return DefaultAssetObject;
    }
    else
    {
        return WeakDefaultAssetObject;
    }
}
